package com.meeting.meetingroom_api.controller;

import com.meeting.meetingroom_api.dto.*;
import com.meeting.meetingroom_api.dto.CancellationRequestDto;
import com.meeting.meetingroom_api.enums.CancellationStatus;
import com.meeting.meetingroom_api.service.CancellationService;
import jakarta.persistence.EntityNotFoundException;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import com.meeting.meetingroom_api.security.UserDetailsImpl;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/cancellations")
public class CancellationController {

    private final CancellationService cancellationService;

    @Autowired
    public CancellationController(CancellationService cancellationService) {
        this.cancellationService = cancellationService;
    }

    //已测试
    @PreAuthorize("hasRole('CUSTOMER')")
    @PostMapping("/request")
    public ResponseEntity<?> requestCancellation(
            @Valid @RequestBody CancellationRequestDto requestDto,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        try {
            CancellationDto cancellationDto = cancellationService.requestCancellation(requestDto, currentUser.getId());
            return ResponseEntity.ok(cancellationDto);
        } catch (IllegalStateException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("message", e.getMessage()));
        } catch (SecurityException e) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN)
                    .body(Map.of("message", e.getMessage()));
        } catch (EntityNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("message", e.getMessage()));
        }
    }

    //已测试
    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @PostMapping("/{cancellationId}/review")
    public ResponseEntity<?> reviewCancellation(
            @PathVariable Integer cancellationId,
            @RequestBody  RejectCancelDto rejectCancelDto,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        try {
            CancellationDto cancellationDto = cancellationService.reviewCancellation(
                    cancellationId, currentUser.getId(), rejectCancelDto.getApproved(), rejectCancelDto.getRejectionReason());
            return ResponseEntity.ok(cancellationDto);
        } catch (IllegalStateException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("message", e.getMessage()));
        } catch (SecurityException e) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN)
                    .body(Map.of("message", e.getMessage()));
        } catch (EntityNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("message", e.getMessage()));
        }
    }

    //用不上，取消订单员工通过后直接退款
    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @PostMapping("/{cancellationId}/process-refund")
    public ResponseEntity<?> processRefund(
            @PathVariable Integer cancellationId,
            @RequestParam String refundTransactionId,
            @RequestParam BigDecimal actualRefundAmount) {
        try {
            CancellationDto cancellationDto = cancellationService.processRefund(
                    cancellationId, refundTransactionId, actualRefundAmount);
            return ResponseEntity.ok(cancellationDto);
        } catch (IllegalStateException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("message", e.getMessage()));
        } catch (EntityNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("message", e.getMessage()));
        }
    }
    //获取单个取消预订的详情
    @GetMapping("/{cancellationId}")
    public ResponseEntity<?> getCancellationDetails(@PathVariable Integer cancellationId) {
        try {
            CancellationDto cancellationDto = cancellationService.getCancellationDetails(cancellationId);
            return ResponseEntity.ok(cancellationDto);
        } catch (EntityNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("message", e.getMessage()));
        }
    }

    @GetMapping("/booking/{bookingId}")
    public ResponseEntity<?> getCancellationByBookingId(@PathVariable Integer bookingId) {
        try {
            CancellationDto cancellationDto = cancellationService.getCancellationDetailsByBookingId(bookingId);
            return ResponseEntity.ok(cancellationDto);
        } catch (EntityNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("message", e.getMessage()));
        }
    }

    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @GetMapping("/pending-reviews")
    public ResponseEntity<Page<CancellationDto>> getPendingReviews(
            @PageableDefault(size = 10, sort = "requestedAt", direction = Sort.Direction.DESC) Pageable pageable) {
        return ResponseEntity.ok(cancellationService.getPendingReviews(pageable));
    }

    @PreAuthorize("hasRole('CUSTOMER')")
    @GetMapping("/my-cancellations")
    public ResponseEntity<Page<CancellationDto>> getCustomerCancellations(
            @AuthenticationPrincipal UserDetailsImpl currentUser,
            @PageableDefault(size = 10, sort = "requestedAt", direction = Sort.Direction.DESC) Pageable pageable) {
        return ResponseEntity.ok(cancellationService.getCustomerCancellations(currentUser.getId(), pageable));
    }

    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @GetMapping("/by-status/{status}")
    public ResponseEntity<?> getCancellationsByStatus(
            @PathVariable String status,
            @PageableDefault(size = 10, sort = "requestedAt", direction = Sort.Direction.DESC) Pageable pageable) {
        try {
            Page<CancellationDto> cancellations = cancellationService.getCancellationsByStatus(status, pageable);
            return ResponseEntity.ok(cancellations);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("message", e.getMessage()));
        }
    }

    @GetMapping("/calculate-refund/{bookingId}")
    public ResponseEntity<?> calculateRefundAndFee(@PathVariable Integer bookingId) {
        try {
            CancellationDto calculation = cancellationService.calculateRefundAndFee(bookingId);
            return ResponseEntity.ok(calculation);
        } catch (EntityNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("message", e.getMessage()));
        }
    }

    @GetMapping("/refund-rules")
    public ResponseEntity<Map<String, String>> getRefundRules() {
        Map<String, String> rules = new LinkedHashMap<>();
        rules.put("72", "提前72小时及以上取消预订，退还全部费用");
        rules.put("48", "提前48-72小时取消预订，退还75%费用");
        rules.put("24", "提前24-48小时取消预订，退还25%费用");
        rules.put("0", "不足24小时不可取消预订");
        return ResponseEntity.ok(rules);
    }
    //客户对于被拒绝的取消预订申请，重新编辑原因，重新发起取消预订申请
    @PreAuthorize("hasRole('CUSTOMER')")
    @PutMapping("/{cancellationId}/resubmit")
    public ResponseEntity<CancellationDto> resubmitCancellation(
            @AuthenticationPrincipal UserDetailsImpl currentUser,
            @PathVariable Integer cancellationId,
            @RequestBody @Valid ResubmitCancellationRequest request
    ) {
        CancellationDto result = cancellationService.resubmitCancellation(
                currentUser.getId(),
                cancellationId,
                request.getReason()
        );
        return ResponseEntity.ok(result);
    }

    //客户确认取消申请（确认员工的审核结果）
    @PreAuthorize("hasRole('CUSTOMER')")
    @PostMapping("/{cancellationId}/confirm")
    public ResponseEntity<?> confirmCancellation(
            @PathVariable Integer cancellationId,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        try {
            CancellationDto cancellationDto = cancellationService.confirmCancellation(
                    cancellationId, currentUser.getId());
            return ResponseEntity.ok(cancellationDto);
        } catch (IllegalStateException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                    .body(Map.of("message", e.getMessage()));
        } catch (SecurityException e) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN)
                    .body(Map.of("message", e.getMessage()));
        } catch (EntityNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("message", e.getMessage()));
        }
    }
    //获取所有客户待确认pending，且已经被员工refunded的取消申请
    @PreAuthorize("hasRole('CUSTOMER')")
    @GetMapping("/my-pending-confirmations")
    public ResponseEntity<Page<CancellationDto>> getMyPendingConfirmations(
            @AuthenticationPrincipal UserDetailsImpl currentUser,
            @PageableDefault(size = 10, sort = "refundedAt", direction = Sort.Direction.DESC) Pageable pageable) {
        return ResponseEntity.ok(cancellationService.getPendingCustomerConfirmations(currentUser.getId(), pageable));
    }
    //客户分页查询状态'pending_review'（待审核）或 'rejected'（被拒绝） 或 'refunded'（已退款） 的取消预订记录
    @PreAuthorize("hasRole('CUSTOMER')")
    @GetMapping("/getCancelByStatus")
    public ResponseEntity<Page<CancellationDto>> getCancelByStatus(
            @AuthenticationPrincipal UserDetailsImpl currentUser,
            @RequestParam CancellationStatus status,
            @PageableDefault(size = 10, sort = "refundedAt", direction = Sort.Direction.DESC) Pageable pageable
            ) {
        return ResponseEntity.ok(cancellationService.getCancelByStatus(currentUser.getId(), status,pageable));
    }
    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @GetMapping("/pending-customer-confirmations")
    public ResponseEntity<Page<CancellationDto>> getAllPendingCustomerConfirmations(
            @PageableDefault(size = 10, sort = "refundedAt", direction = Sort.Direction.DESC) Pageable pageable) {
        return ResponseEntity.ok(cancellationService.getAllPendingCustomerConfirmations(pageable));
    }
}